package com.budweiser.user.service.impl;

import com.budweiser.commons.utils.PageUtil;
import com.budweiser.model.core.constants.BaccoCoreMq;
import com.budweiser.model.organ.Organization;
import com.budweiser.model.page.Page;
import com.budweiser.model.user.*;
import com.budweiser.model.user.constants.CredentialType;
import com.budweiser.user.dao.OrganizationDao;
import com.budweiser.user.dao.UserCredentialsDao;
import com.budweiser.user.dao.UserDao;
import com.budweiser.user.dao.UserRoleDao;
import com.budweiser.user.dto.UserDto;
import com.budweiser.user.service.PermissionService;
import com.budweiser.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@Transactional
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
    @Autowired
    private UserCredentialsDao userCredentialsDao;
    @Autowired
    UserRoleDao userRoleDao;
    @Autowired
    private PermissionService permissionService;
    @Autowired
    private BCryptPasswordEncoder passwordEncoder;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private OrganizationDao organizationDao;

    @Override
    public LoginUser findByUsername(String username) {
        User user = userCredentialsDao.findUserByUsername(username);
        if (user != null) {
            LoginUser loginUser = new LoginUser();
            BeanUtils.copyProperties(user, loginUser);
            Set<Role> sysRoles = userRoleDao.findRolesByUserId(user.getId());
            loginUser.setRoles(sysRoles);// 设置角色
            if (!CollectionUtils.isEmpty(sysRoles)) {
                Set<Long> roleIds = sysRoles.parallelStream().map(Role::getId).collect(Collectors.toSet());
                Set<Permission> sysPermissions = permissionService.findByRoleIds(roleIds);
                if (!CollectionUtils.isEmpty(sysPermissions)) {
                    Set<String> permissions = sysPermissions.parallelStream().map(Permission::getPermission)
                            .collect(Collectors.toSet());
                    loginUser.setPermissions(permissions);// 设置权限集合
                }
            }
            return loginUser;
        }
        log.info("根据登陆查询登陆用户信息", username);
        return null;
    }

    @Override
    public Page<User> findUsers(Map<String, Object> params) {
        int count = userDao.count(params);
        List<User> users = Collections.emptyList();
        if (count > 0) {
            PageUtil.pageParamConver(params, true);
            users = userDao.findData(params);
        }
        return new Page<User>(count, users);
    }

    @Override
    public void save(User user) {
        user.setDeleteStatus(false);
        user.setEnabled(true);
        user.setCreateTime(new Date());
        user.setUpdateTime(new Date());
        UserCredential userCredential = userCredentialsDao.findByUsername(user.getUsername());
        if (userCredential != null) {
            throw new IllegalArgumentException("用户名已存在");
        }
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        log.info("新增用户{}", user);
        userDao.insert(user);
        userCredentialsDao.save(new UserCredential(user.getUsername(), CredentialType.USERNAME.name(), user.getId()));
        amqpTemplate.convertAndSend(BaccoCoreMq.MQ_EXCHANGE_CORE, BaccoCoreMq.ROUTING_KEY_ACT_SAVE,
                "USER," + user.getId());
    }

    @Override
    public void update(User user) {
        user.setUpdateTime(new Date());
        userCredentialsDao.deleteByName(user.getUsername());
        userCredentialsDao.save(new UserCredential(user.getUsername(), CredentialType.USERNAME.name(), user.getId()));
        log.info("修改用户{}", user);
        userDao.update(user);
        amqpTemplate.convertAndSend(BaccoCoreMq.MQ_EXCHANGE_CORE, BaccoCoreMq.ROUTING_KEY_ACT_UPDATE,
                "USER," + user.getId());
    }

    @Override
    public void del(List<Long> ids) {
        log.info("删除用户{}", ids);
        userDao.updateDelStatus(ids);
        amqpTemplate.convertAndSend(BaccoCoreMq.MQ_EXCHANGE_CORE, BaccoCoreMq.ROUTING_KEY_ACT_USER_DELETE, ids);
    }

    @Override
    public List<Role> findUserRole(Long userid) {
        log.info("根据用户id查询角色{}", userid);
        return userRoleDao.findUserRole(userid);
    }

    /***
     * 给用戶设置角色
     */
    @Override
    public void setUserToRole(Long userid, List<Long> roleids) {
        // 选出用户全部角色
        userRoleDao.delete(userid, null);
        if (!CollectionUtils.isEmpty(roleids)) {
            roleids.forEach(r -> {
                userRoleDao.save(userid, r);
            });
        }
    }

    @Override
    public User findUserId(Long id) {
        return userDao.findUserId(id);
    }


    private Long getOrgid(String orgname) {
        Organization organization = organizationDao.getOrganizationByName(orgname);
        if (organization != null) {
            return organization.getId();
        }
        return null;
    }

    @Override
    public Page<UserDto> getUsers(Map<String, Object> params) {
        int count = userDao.total(params);
        List<UserDto> userDtos = Collections.emptyList();
        if (count > 0) {
            PageUtil.pageParamConver(params, true);
            userDtos = userDao.getUserData(params);
        }
        return new Page<UserDto>(count, userDtos);
    }

    @Override
    public List<UserDto> getUserByOrgName(String orgname) {
        return userDao.getUserByOrgName(orgname);
    }

    @Override
    public void add(User user) {
//        user.setId(1111111l);
        user.setCreateTime(new Date());
        user.setUpdateTime(new Date());
        user.setPassword(passwordEncoder.encode("123456"));
        user.setEnabled(true);
        user.setDeleteStatus(false);
        userDao.add(user);
    }
}
